import 'dart:convert';
import 'dart:io';
import 'package:flutter/services.dart';
import 'package:mime/mime.dart';
import 'package:path/path.dart' as p;
import 'package:path_provider/path_provider.dart';
import 'package:shelf/shelf.dart' as shelf;
import 'package:shelf/shelf_io.dart' as io;
import 'package:shelf_router/shelf_router.dart';
import 'package:shelf_static/shelf_static.dart';

class LocalWebServer {
  late HttpServer _server;
  final int port;
  List<File> _selectedFiles = [];

  LocalWebServer({this.port = 8080});


  Future<String> start() async {
    final router = Router();

    //final htmlDir = await _copyAssetsToLocal();
    //router.mount('/web/', createStaticHandler(htmlDir, defaultDocument: 'index.html'));

    router.get('/download/<filename>', (shelf.Request request, String filename) async {
      final targetFile = _selectedFiles.firstWhere(
            (file) => p.basename(file.path) == filename,
        orElse: () => throw shelf.Response.notFound('文件不存在'),
      );

      final fileContent = await targetFile.readAsBytes();
      return shelf.Response.ok(
        fileContent,
        headers: {
          'Content-Type': _getMimeType(targetFile.path),
          'Content-Disposition': 'attachment; filename*=UTF-8\'\'${Uri.encodeComponent(p.basename(targetFile.path))}',
        },
      );
    });

    _server = await io.serve(
      router,
      InternetAddress.anyIPv4,
      port,
    );

    return 'http://${_server.address.host}:${_server.port}';
  }

  void updateSelectedFiles(List<File> files) => _selectedFiles = files;


  Future<void> stop() async => await _server.close();

  Future<String> _copyAssetsToLocal() async {
    final appDocDir = await getApplicationDocumentsDirectory();
    final targetDir = p.join(appDocDir.path, 'web');
    final targetDirExists = await Directory(targetDir).exists();

    if (!targetDirExists) await Directory(targetDir).create(recursive: true);

    // 读取assets清单并复制文件
    final manifestContent = await rootBundle.loadString('AssetManifest.json');
    final assets = Map<String, dynamic>.from(json.decode(manifestContent));
    final webAssets = assets.keys.where((path) => path.startsWith('assets/web/')).toList();

    for (final assetPath in webAssets) {
      final targetPath = p.join(targetDir, p.relative(assetPath, from: 'assets/web'));
      final file = File(targetPath);
      if (!await file.exists()) {
        await file.parent.create(recursive: true);
        final bytes = await rootBundle.load(assetPath);
        await file.writeAsBytes(bytes.buffer.asUint8List());
      }
    }

    return targetDir;
  }


  String _getMimeType(String filePath) {
    final mimeType = lookupMimeType(filePath);
    return mimeType ?? 'application/octet-stream';
  }
}